//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
/*
 * start-pxa: PXA (XScale) specific start code
 *
 * This code is modified to Monahans booting up process by Stanley Cai
 * Only for internal use!!!
 *
 * Copyright (C) 2002 Intel Corporation
 * Written by Rusty Geldmacher (russell.r.geldmacher@intel.com)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include <arch.h>

.text

/*
 * We start by implementing *all* exception vectors
 *
 * Reset vector: this initialises the machine
 * note here that this not yet taken sleep wakeup into account -- lets just
 * get something to work first.
 */

.macro blink, count
	mov		r3, \count
	b		endless_blink
.endm

.macro cpwait reg
	        mrc  p15,0,\reg,c2,c0,0
	        mov  \reg,\reg
	        sub  pc,pc,#4
.endm

.globl _start
_start:
	b	reset
	b	undefined_instruction
	b	software_interrupt
	b	prefetch_abort
	b	data_abort
	b	not_used
	b	irq
	b	fiq

reset:
	/* set CPU to SVC32 mode */
	/* Is this necessary to new BLOB? -sc */
	mrs		r0, cpsr
	bic		r0, r0, #0x1f
	orr		r0, r0, #0x13
	msr		cpsr, r0

	/* First, mask **ALL** interrupts */
	/* Step 1 - Enable CP6 permission */
	mrc	p15, 0, r1, c15, c1, 0  @ read CPAR
	orr	r1, r1, #0x40
	mcr	p15, 0, r1, c15, c1, 0
	cpwait	r1

	/* Step 2 - Mask ICMR & ICMR2 */
	mov	r1, #0
    mcr p6, 0, r1, c1, c0, 0    @ ICMR
	mcr	p6, 0, r1, c7, c0, 0	@ ICMR2

real_reset:
	bl		gpiosetup
	bl		memsetup

#if 0
	@ Check to see if we're coming out of low-power reset.
	@ If so, jump to the resume code
        ldr r0, =ARSR
        ldr r1, [r0]
        tst r1, #4

        ldrne r0, =PSPR
        ldrne r1, [r0]
        movne pc, r1
#endif

@********************************************************************
@ Disable (mask) all interrupts at the interrupt controller
@

@ clear the interrupt level register (use IRQ, not FIQ)
@
        mov     r1, #0
        mcr     p6, 0, r1, c2, c0, 0    @ ICLR

@ mask all interrupts at the controller
@
        mcr     p6, 0, r1, c1, c0, 0    @ ICMR
	mcr	p6, 0, r1, c7, c0, 0	@ ICMR2

@ ********************************************************************
@ Disable the peripheral clocks, and set the core clock
@ frequency (hard-coding at 398.12MHz for now).
@

@ Turn Off ALL on-chip peripheral clocks for re-configuration
@ *Note: See label 'ENABLECLKS' for the re-enabling
@
        ldr     r1,  =CKENA
        ldr     r2,  =(CKENA_22_FFUART|CKENA_10_SRAM|CKENA_9_SMC|CKENA_8_DMC)
        str     r2,  [r1]
        ldr     r1,  =CKENB
        ldr     r2,  =(CKENB_6_IRQ)
        str     r2,  [r1]

@@ scrub/init SDRAM if enabled/present
        ldr     r11, =0xa0000000 // base address of SDRAM
        ldr     r12, =0x04000000 // size of memory to scrub
        mov     r8,r12           // save DRAM size
        mov     r0, #0           // scrub with 0x0000:0000
        mov     r1, #0
        mov     r2, #0
        mov     r3, #0
        mov     r4, #0
        mov     r5, #0
        mov     r6, #0
        mov     r7, #0

	@@ fastScrubLoop
10:
        subs    r12, r12, #32   // 32 bytes/line
        stmia   r11!, {r0-r7}
        beq     15f
        b       10b
15:

@ Mask all interrupts
        mov     r1, #0
        mcr     p6, 0, r1, c1, c0, 0    @ ICMR

@ Disable software and data breakpoints
        mov     r0, #0
        mcr     p15,0,r0,c14,c8,0  // ibcr0
        mcr     p15,0,r0,c14,c9,0  // ibcr1
        mcr     p15,0,r0,c14,c4,0  // dbcon

@ Enable all debug functionality
        mov     r0,#0x80000000
        mcr     p14,0,r0,c10,c0,0  // dcsr

	bl		_c_main

	blink	#1

.globl undefined_instruction
undefined_instruction:
	blink	#2

.globl software_interrupt
software_interrupt:
	blink	#3

.globl prefetch_abort
prefetch_abort:
	blink	#4

.globl data_abort
data_abort:
	blink	#5

.globl not_used
not_used:
	blink	#6

.globl irq
irq:
	blink	#7

.globl fiq
fiq:
	blink	#8


/* Keep this function, Zylonite board has no GPIO led now. */
endless_blink:
	@wait	#0x2000000
	b		endless_blink

